// BizElements.Web.CommandMenu control.

var Biz_CommandMenu_ResponseWaitIntervalInMs = 50;
var Biz_CommandMenu_MaxEndResponseAttempts = 100;
var Biz_CommandMenu_MenuIDsWithPendingAsyncPostBacks = new Array();

function Biz_CommandMenu_MonitorInIntervals(sMenuId, iItemCount, sTxtDisabledItemsId, sTxtHiddenItemsId, sTxtDisabledToolTips)
{    
    var ctlDisabledItemsTxt = document.getElementById(sTxtDisabledItemsId);
    var bNewMessageHasArrivedFromServer = (ctlDisabledItemsTxt != null  &&  ctlDisabledItemsTxt.value != null  &&  ctlDisabledItemsTxt.value != "");
    if (bNewMessageHasArrivedFromServer)
    {
        try { Biz_CommandMenu_SetItems(sMenuId, iItemCount, sTxtDisabledItemsId, sTxtHiddenItemsId, sTxtDisabledToolTips); }
        catch (e){}
    }

    var sMonitorInIntervalsFunctionCall = "Biz_CommandMenu_MonitorInIntervals('" + sMenuId + "', " + iItemCount + ", '" + sTxtDisabledItemsId + "', '" + sTxtHiddenItemsId + "', '" + sTxtDisabledToolTips + "');";
    setTimeout(sMonitorInIntervalsFunctionCall, 50);
}


// Show (init horizontal security checks), hide menu.

function Biz_CommandMenu_Show(evt, sMenuId, sBtnAsyncCheckCommandsId, iItemCount, sTxtDisabledItemsId, sTxtHiddenItemsId, sTxtDisabledToolTips, bAsyncPostBackOnShow)
{
    if (window.event != null)
        evt = window.event;  

    if (evt == null)
        return;

    var x = (evt.x != null) ? evt.x : evt.clientX;
    var y = (evt.y != null) ? evt.y : evt.clientY;
    var scrollTop = (window.pageYOffset)?(window.pageYOffset):(document.documentElement)?document.documentElement.scrollTop:document.body.scrollTop;
    var scrollLeft = (window.pageXOffset)?(window.pageXOffset):(document.documentElement)?document.documentElement.scrollLeft:document.body.scrollLeft;

    Biz_CommandMenu_BeginShow(x, y, scrollTop, scrollLeft, sMenuId, sBtnAsyncCheckCommandsId, iItemCount, sTxtDisabledItemsId, sTxtHiddenItemsId, sTxtDisabledToolTips, bAsyncPostBackOnShow);
}

function Biz_CommandMenu_BeginShow(x, y, scrollTop, scrollLeft, sMenuId, sBtnAsyncCheckCommandsId, iItemCount, sTxtDisabledItemsId, sTxtHiddenItemsId, sTxtDisabledToolTips, bAsyncPostBackOnShow)
{
    // Don't allow multiple async requests for the same menu. Users cannot randomly click around.
    // This means that the menu will be left open for the previously selected record/parameter-set and 
    // may enable commands which are not allowed for current record. This might lead to some confusion.
    // However, the server-side component which executes the command will check the permissions once again.
    var bHasPendingRequest = false;
    for (var idxMenuIdWithPendingRequest = 0; idxMenuIdWithPendingRequest < Biz_CommandMenu_MenuIDsWithPendingAsyncPostBacks.length; idxMenuIdWithPendingRequest++)
    {
        if (Biz_CommandMenu_MenuIDsWithPendingAsyncPostBacks[idxMenuIdWithPendingRequest] == sMenuId)
            bHasPendingRequest = true;
    }
    if (bHasPendingRequest)
        return;

    Biz_CommandMenu_EndShow(x, y, scrollTop, scrollLeft, sMenuId, sBtnAsyncCheckCommandsId, iItemCount, sTxtDisabledItemsId, sTxtHiddenItemsId, sTxtDisabledToolTips, bAsyncPostBackOnShow);
}

function Biz_CommandMenu_EndShow(x, y, scrollTop, scrollLeft, sMenuId, sBtnAsyncCheckCommandsId, iItemCount, sTxtDisabledItemsId, sTxtHiddenItemsId, sTxtDisabledToolTips, bAsyncPostBackOnShow)
{
    var ctlMenu = document.getElementById(sMenuId);	    
    if (ctlMenu != null)
    {        
        // Prevent previously registered document.onclick handlers to hide the current menu (FireFox).
        document.onclick = null;
        
        if (bAsyncPostBackOnShow)
            Biz_CommandMenu_BeginEnforceHorizontalSecurity(sMenuId, sBtnAsyncCheckCommandsId, iItemCount, sTxtDisabledItemsId, sTxtHiddenItemsId, sTxtDisabledToolTips);
        
        ctlMenu.style.position = "absolute";
        // FireFox requires that left and top style attributes are not integers but units, thus the 'px' suffix. 
        ctlMenu.style.left = x + scrollLeft + 'px';
        ctlMenu.style.top = y + scrollTop + 'px';
        ctlMenu.style.zIndex = 100;
        ctlMenu.style.visibility = "visible";
        
        // Register document.onclick handler which hides the menu. 
        // setTimeout required by FireFox. Otherwise the currently processed event would hide the menu.
        setTimeout("document.onclick = function Biz_CommandMenu_HideOnClick(){Biz_CommandMenu_Hide('" + sMenuId + "');};", 200);
    }
}

function Biz_CommandMenu_Hide(sMenuId)
{
    // Unregister document.onclick handler (FireFox) to prevent hiding new menus.
    document.onclick = null;
    
    // Hide menu.
    var ctlMenu = document.getElementById(sMenuId);
    if (ctlMenu != null)
    {
        ctlMenu.style.zIndex = -1;
        ctlMenu.style.visibility = "hidden";
    }       
}


// Async horizontal security checks.

function Biz_CommandMenu_BeginEnforceHorizontalSecurity(sMenuId, sBtnAsyncCheckCommandsId, iItemCount, sTxtDisabledItemsId, sTxtHiddenItemsId, sTxtDisabledToolTips)
{
    // Enable all, async request will determine if something has to be disabled.
    Biz_CommandMenu_EnableAll(sMenuId, iItemCount);
    
    // If defined, the button raises an AsyncPostBackTrigger for the CommandMenu control.
    if (sMenuId == null || sBtnAsyncCheckCommandsId == null || iItemCount == null || sTxtDisabledItemsId == null || sTxtHiddenItemsId == null || sMenuId == "" || sBtnAsyncCheckCommandsId == "" || iItemCount == 0 || sTxtDisabledItemsId == "" || sTxtHiddenItemsId == "")
        return;        
        
    var btnAsyncCheckCommands = document.getElementById(sBtnAsyncCheckCommandsId);
    var ctlDisabledItemsTxt = document.getElementById(sTxtDisabledItemsId);
    var ctlHiddenItemsTxt = document.getElementById(sTxtHiddenItemsId);
    if (btnAsyncCheckCommands == null  ||  ctlDisabledItemsTxt == null  ||  ctlHiddenItemsTxt == null)
        return;
        
    ctlDisabledItemsTxt.value = "";
    ctlHiddenItemsTxt.value = "";
    
    // Mark the menu as having an async request. Only one async request is allowed per menu.    
    Biz_CommandMenu_AddToListOfMenusWithPendingRequests(sMenuId);
    // Initiate async postback. Cannot use "btnAsyncCheckCommands.click();" because it initiates a full/sync PostBack in FireFox.
    Sys.WebForms.PageRequestManager.getInstance()._doPostBack(sBtnAsyncCheckCommandsId, "");
    // Wait for server response and process it if it arrives before timeout.
    Biz_CommandMenu_EndEnforceHorizontalSecurity(sMenuId, iItemCount, sTxtDisabledItemsId, sTxtHiddenItemsId, sTxtDisabledToolTips, 0);
}

function Biz_CommandMenu_EndEnforceHorizontalSecurity(sMenuId, iItemCount, sTxtDisabledItemsId, sTxtHiddenItemsId, sTxtDisabledToolTips, iEndResponseAttempt)
{    
    // If not items are to be disabled/hidden, the textboxes contain a ';' character.
    // Otherwise they contain semicolon delimited IDs of the menu items (rows) to be disabled/hidden.
    // Biz_CommandMenu_SetItems function clears the values (including the ';' chars) received from the server.
    if (iEndResponseAttempt == null)
        return;
    
    var ctlDisabledItemsTxt = document.getElementById(sTxtDisabledItemsId);
    if (ctlDisabledItemsTxt == null)
        return;
    
    var bServerResponded = (ctlDisabledItemsTxt.value != "");
    if (bServerResponded)
    {
        Biz_CommandMenu_RemoveFromListOfMenusWithPendingRequests(sMenuId);
        Biz_CommandMenu_SetItems(sMenuId, iItemCount, sTxtDisabledItemsId, sTxtHiddenItemsId, sTxtDisabledToolTips);
    }
    else
    {
        var bGiveUp = (iEndResponseAttempt > Biz_CommandMenu_MaxEndResponseAttempts);
        if (bGiveUp)
        {
            Biz_CommandMenu_RemoveFromListOfMenusWithPendingRequests(sMenuId);
            return;
        }

        iEndResponseAttempt++;
        var sEndEnforceHorizontalSecurityFunctionCall = "Biz_CommandMenu_EndEnforceHorizontalSecurity('" + sMenuId + "', " + iItemCount + ", '" + sTxtDisabledItemsId + "', '" + sTxtHiddenItemsId + "', '" + sTxtDisabledToolTips + "', " + iEndResponseAttempt + "); ";
        setTimeout(sEndEnforceHorizontalSecurityFunctionCall, Biz_CommandMenu_ResponseWaitIntervalInMs);
    }         
}

function Biz_CommandMenu_AddToListOfMenusWithPendingRequests(sMenuId)
{
    var idxInPendingMenusWithRequest = -1;
    for (var idxMenuIdWithPendingRequest = 0; idxMenuIdWithPendingRequest < Biz_CommandMenu_MenuIDsWithPendingAsyncPostBacks.length; idxMenuIdWithPendingRequest++)
    {
        if (Biz_CommandMenu_MenuIDsWithPendingAsyncPostBacks[idxMenuIdWithPendingRequest] == sMenuId)
            idxInPendingMenusWithRequest = idxMenuIdWithPendingRequest;
    }
    if (idxInPendingMenusWithRequest < 0)
        idxInPendingMenusWithRequest = Biz_CommandMenu_MenuIDsWithPendingAsyncPostBacks.length;

    Biz_CommandMenu_MenuIDsWithPendingAsyncPostBacks[idxInPendingMenusWithRequest] = sMenuId;
}

function Biz_CommandMenu_RemoveFromListOfMenusWithPendingRequests(sMenuId)
{
    var idxInPendingMenusWithRequest = -1;
    for (var idxMenuIdWithPendingRequest = 0; idxMenuIdWithPendingRequest < Biz_CommandMenu_MenuIDsWithPendingAsyncPostBacks.length; idxMenuIdWithPendingRequest++)
    {
        if (Biz_CommandMenu_MenuIDsWithPendingAsyncPostBacks[idxMenuIdWithPendingRequest] == sMenuId)
            idxInPendingMenusWithRequest = idxMenuIdWithPendingRequest;
    }
    
    if (idxInPendingMenusWithRequest >= 0)
        Biz_CommandMenu_MenuIDsWithPendingAsyncPostBacks.splice(idxInPendingMenusWithRequest, 1);
}


// Enable, disable/hide menu items.

function Biz_CommandMenu_SetItems(sMenuId, iItemCount, sTxtDisabledItemsId, sTxtHiddenItemsId, sTxtDisabledToolTips)
{
    Biz_CommandMenu_EnableAll(sMenuId, iItemCount);
    
    var ctlDisabledItemsTxt = document.getElementById(sTxtDisabledItemsId);
    var ctlDisabledToolTipsTxt = document.getElementById(sTxtDisabledToolTips);
    if (ctlDisabledItemsTxt != null)
    {
        var arrItemIDsToDisable = ctlDisabledItemsTxt.value.split(";");
        ctlDisabledItemsTxt.value = "";
        var arrToolTips = (ctlDisabledToolTipsTxt != null) ? ctlDisabledToolTipsTxt.value.split(";") : new Array();
        if (ctlDisabledToolTipsTxt != null)
            ctlDisabledToolTipsTxt.value = "";
        
        for (var idxItem=0; idxItem<arrItemIDsToDisable.length; idxItem++)
        {
            var sDisabledItemTooltip = (arrToolTips.length > idxItem) ? arrToolTips[idxItem] : null;
            if (arrItemIDsToDisable[idxItem] != "")
                Biz_CommandMenu_DisableItem(arrItemIDsToDisable[idxItem], sDisabledItemTooltip);
        }
    }
    
    var ctlHiddenItemsTxt = document.getElementById(sTxtHiddenItemsId);
    if (ctlHiddenItemsTxt != null)
    {
        var arrItemIDsToHide = ctlHiddenItemsTxt.value.split(";");
        ctlHiddenItemsTxt.value = "";
        for (var idxItem=0; idxItem<arrItemIDsToHide.length; idxItem++)
        {
            if (arrItemIDsToHide[idxItem] != "")
                Biz_CommandMenu_HideItem(arrItemIDsToHide[idxItem]);
        }
    }
}

function Biz_CommandMenu_EnableAll(sMenuId, iItemCount)
{    
    for (var idxItem=0; idxItem<iItemCount; idxItem++)
    {
        var sItemRowId = sMenuId + "n" + idxItem;
        Biz_CommandMenu_EnableItem(sItemRowId);        
    }
}

function Biz_CommandMenu_EnableItem(sItemRowId)
{    
    if (sItemRowId == null  ||  sItemRowId == "")
        return;
    
    var ctlItemRow = document.getElementById(sItemRowId);
    if (ctlItemRow == null)
        return;
    
    if (ctlItemRow.style.display == "none")
        ctlItemRow.style.display = "";

    if (ctlItemRow.BizOldTitle != null)
        ctlItemRow.title = ctlItemRow.BizOldTitle;
    
    try
    {
        // Assign do nothing function. Propagate events to child elements.
        ctlItemRow.onclick = null;
        ctlItemRow.firstChild.disabled = "";
        
        // disabled="disabled" doesn't gray-out the child A element in FireFox. It is manually grayed/ungrayed.
        var bIsMsInternetExplorer = (navigator.userAgent.indexOf("MSIE") >= 0);
        if (!bIsMsInternetExplorer)
        {
            var arrLinks = ctlItemRow.getElementsByTagName("A");
            for (var idxLink=0; idxLink<arrLinks.length; idxLink++)
            {
                var ctlLink = arrLinks[idxLink];
                if (ctlLink.BizOldColor != null)
                    ctlLink.style.color = ctlLink.BizOldColor;
            }
        }
    }
    catch (e)
    {
    }
}

function Biz_CommandMenu_DisableItem(sItemRowId, sDisabledItemTooltip)
{    
    // Simple <tr>.disabled='disabled' doesn't work, since the click event is propagated to <a> element.
    // We emulate 'disabled' mode by intercepting mouse events on the <tr> element level and disabling,
    // ie. graying out, the first <td> element. Element hierarchy: TR -> TD -> TABLE -> TR -> TD -> A.    
    if (sItemRowId == null  ||  sItemRowId == "")
        return;
        
    var ctlItemRow = document.getElementById(sItemRowId);
    if (ctlItemRow == null)
        return;
    
    if (sDisabledItemTooltip != null && sDisabledItemTooltip != "")
    {
        if (ctlItemRow.BizOldTitle == null)
            ctlItemRow.BizOldTitle = ctlItemRow.title;
            
        ctlItemRow.title = sDisabledItemTooltip;               
    }              
    
    try
    {        
        // Don't propagate events to child elements.
        ctlItemRow.onclick = new Function("return false;");
        ctlItemRow.firstChild.disabled = "disabled";
        
        // disabled="disabled" doesn't gray-out the child A element in FireFox. It is manually grayed/ungrayed.
        var bIsMsInternetExplorer = (navigator.userAgent.indexOf("MSIE") >= 0);
        if (!bIsMsInternetExplorer)
        {
            var arrLinks = ctlItemRow.getElementsByTagName("A");
            for (var idxLink=0; idxLink<arrLinks.length; idxLink++)
            {
                var ctlLink = arrLinks[idxLink];
                if (ctlLink.BizOldColor == null)
                    ctlLink.BizOldColor = ctlLink.style.color;
                    
                ctlLink.style.color = "Gray";  
            }
        }
    }
    catch (e)
    {
    }
}

function Biz_CommandMenu_HideItem(sItemRowId)
{
    if (sItemRowId == null  ||  sItemRowId == "")
        return;

    var ctlItemRow = document.getElementById(sItemRowId);
    if (ctlItemRow != null)
        ctlItemRow.style.display = "none";
}
